package com.example.ojcodesandbox.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitMQConfig {

  //@Bean
//  public ConnectionFactory connectionFactory() {
//    CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
//    connectionFactory.setAddresses("192.168.147.128:5672");
//    connectionFactory.setUsername("guest");
//    connectionFactory.setPassword("guest");
//    connectionFactory.setPublisherConfirms(true);//消息確認
//    connectionFactory.setPublisherReturns(true);
//    return connectionFactory;
//  }
  @Bean
  public MessageConverter jsonMessageConverter(ObjectMapper objectMapper) {
    return new Jackson2JsonMessageConverter(objectMapper);
  }
  /**
   * 配置rabbitmq连接工厂
   * @param factory
   * @return
   */
  @Bean
  public RabbitTemplate rabbitTemplate(ConnectionFactory factory) {
    RabbitTemplate template = new RabbitTemplate();
    template.setConnectionFactory(factory);
    // 默认是jdk序列化，配置json序列化
    template.setMessageConverter(new Jackson2JsonMessageConverter());
    //设置开启Mandatory,才能触发回调函数,无论消息推送结果怎么样都强制调用回调函数
    template.setMandatory(true);
    template.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
      @Override
      public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        System.out.println("确认回调-相关数据："+correlationData);
        System.out.println("确认回调-确认情况："+ack);
        System.out.println("确认回调-原因："+cause);
      }
    });
    template.setReturnsCallback(new RabbitTemplate.ReturnsCallback() {
      @Override
      public void returnedMessage(ReturnedMessage returnedMessage) {
        System.out.println("消息体："+returnedMessage.getMessage().toString());
        System.out.println("交换机："+returnedMessage.getExchange().toString());
        System.out.println("1"+returnedMessage.getReplyText());
        System.out.println("route key:"+returnedMessage.getRoutingKey());
        System.out.println("reply code:"+returnedMessage.getReplyCode());
      }
    });
    return template;
  }

  //定义交换机
  @Bean
  public DirectExchange QuestionExchange() {
    return ExchangeBuilder.directExchange("questionExchange").durable(true).build();
  }

  //定义执行代码队列
  @Bean
  public Queue QuestionQueue() {
    return QueueBuilder.durable("questionQueue").build();
  }

  //定义返回结果队列
  @Bean
  public Queue ReturnResQueue() {
    return QueueBuilder.durable("returnResQueue").build();
  }

  //定义状态更新队列
  @Bean
  public Queue updateQueue() {
    return QueueBuilder.durable("updateQueue").build();
  }

  //绑定队列和交换机
  @Bean
  public Binding QuestionBinding() {
    return BindingBuilder.bind(QuestionQueue()).to(QuestionExchange()).with("question");
  }

  //绑定队列和交换机
  @Bean
  public Binding ReturnResBinding() {
    return BindingBuilder.bind(ReturnResQueue()).to(QuestionExchange()).with("return");
  }

  //绑定队列和交换机
  @Bean
  public Binding updateBinding() {
    return BindingBuilder.bind(updateQueue()).to(QuestionExchange()).with("update");
  }
}
